home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / GRAPHICS / GIF2RPC.SPK / source / 16bpp_66bit / c / dither2x2 < prev    next >
Text File  |  1995-10-16  |  5KB  |  183 lines

  1. /* dither2x2.c
  2.  * AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  3.  * LICENSE:     FreeWare, Copyright (c) 1995 Cy Booker
  4.  */
  5.  
  6. #include "internal.h"
  7.  
  8. #include <assert.h>
  9. #include <string.h>             /* memset() */
  10.  
  11. #include "OS:macros.h"
  12. #include "OS:hourglass.h"
  13.  
  14.  
  15.  
  16. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  17.  */
  18.  
  19. static void calculate_dither2x2(
  20.                 int             dither[2][2],
  21.                 os_colour       colour);
  22.                 
  23.  
  24.  
  25. static bits map_palette_entry_to_16bpp_colour(
  26.                 os_colour       colour);
  27.  
  28.  
  29.  
  30. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  31.  */
  32.  
  33. extern bool process_gif_16bpp_dither2x2_66bit(
  34.                 const process_gif       *p) {
  35.   byte                  *rove;
  36.   bits                  dest;
  37.   int                   width, height;
  38.   int                   x, y;
  39.   const os_colour       *palette;
  40.   int                   line_length;
  41.   int                   index;
  42.   int                   dither[256][2][2];
  43.  
  44.   assert(p);
  45.   assert(p->pixel_width > 0);
  46.   assert(p->pixel_height > 0);
  47.   assert(p->in_palette.colours);
  48.  
  49.   /*
  50.    * pre-calculate dither table
  51.    * to save a function call in middle loop
  52.    * thus the compiler has more registers to play with
  53.    */
  54.   palette = p->in_palette.colours;
  55.   for (index= p->in_palette.ncolours; (index > 0); ) {
  56.     index--;
  57.     calculate_dither2x2(dither[index], palette[index]);
  58.   }
  59.  
  60.   /*
  61.    * not we pre-load values from the process_gif array
  62.    * because it considerably helps the compiler produce better code
  63.    */
  64.   rove = p->buffer;
  65.   width = (p->pixel_width + 1) & ~1;
  66.   height = p->pixel_height;
  67.   line_length = p->line_length;
  68.   
  69.   for (y= height; (y > 0); y--) {
  70.     if ((y & 7) == 0) {
  71.       xhourglass_percentage((y * 100) / height);
  72.     }
  73.     for (x= width - 1; (x >= 0); x--) {
  74.       assert((x & 1) == 1);
  75.       /*
  76.        * writing one 32-bit word is much faster than two 16-bit shorts
  77.        */
  78.       index = rove[x];
  79.       dest = dither[index][y & 1][x & 1];
  80.       x--;
  81.       index = rove[x];
  82.       dest <<= 16;
  83.       dest |= dither[index][y & 1][x & 1];
  84.       *(((int *)rove) + (((unsigned int)x) >> 1)) = dest;
  85.     }
  86.     rove += line_length;
  87.   }
  88.   return FALSE;
  89. }
  90.  
  91.  
  92.  
  93. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  94.  * strictly speaking, this isn't a 66bit routine!
  95.  * but I can't be arsed to recode it so it is, as the 48 bit routines are faster
  96.  */
  97.  
  98. static void calculate_dither2x2(
  99.                 int             dither[2][2],
  100.                 os_colour       colour) {
  101.   int   target_r, target_g, target_b;
  102.   int   r, g, b;
  103.   bits  tl;
  104.   int   tl_r, tl_g, tl_b;
  105.   bits  br;
  106.   int   br_r, br_g, br_b;
  107.   bits  tr;
  108.   int   tr_r, tr_g, tr_b;
  109.   bits  bl;
  110.  
  111.   /*
  112.    * we now use ``colourtrans'' dithering algorithm, where X is the
  113.    * destination colour, and all values are (r, g, b) tuples
  114.    * topleft <-- X
  115.    * bottomright <-- X - (topleft - X)
  116.    * topright <-- X - (((topleft - X) + (bottomright - X)) / 2)
  117.    * bottomleft <-- X - (((topleft - X) + (bottomright - X) + (topright - X)) / 3)
  118.    *
  119.    * personally, I don't see why the need for divisions, as surely we are using:
  120.    *    "OK we missed X by N, therefore compensate by choosing X - N"
  121.    * but colourtrans is doing
  122.    *    missed by TL and missed by BR, therefore try X - ((TL+TR)/2)
  123.    *
  124.    * humph, it works, anyway
  125.    */
  126.  
  127.   target_r = 31 * ((colour >> 8) & 0xff);
  128.   target_g = 31 * ((colour >> 16) & 0xff);
  129.   target_b = 31 * ((colour >> 24) & 0xff);
  130.   tl = map_palette_entry_to_16bpp_colour(colour);
  131.   tl_r = 255 * ((tl >> 0) & 0x1f);
  132.   r = MAX((2 * target_r) - tl_r, 0) / 31;
  133.   r = MIN(255, r);
  134.   tl_g = 255 * ((tl >> 5) & 0x1f);
  135.   g = MAX((2 * target_g) - tl_g, 0) / 31;
  136.   g = MIN(255, g);
  137.   tl_b = 255 * ((tl >> 10) & 0x1f);
  138.   b = MAX((2 * target_b) - tl_b, 0) / 31;
  139.   b = MIN(255, b);
  140.   br = map_palette_entry_to_16bpp_colour((r << 8) | (g << 16) | (b << 24));
  141.  
  142.   br_r = 255 * ((br >> 0) & 0x1f);
  143.   r = MAX((2 * 2 * target_r) - (tl_r + br_r), 0) / (2*31);
  144.   r = MIN(255, r);
  145.   br_g = 255 * ((br >> 5) & 0x1f);
  146.   g = MAX((2 * 2 * target_g) - (tl_g + br_g), 0) / (2*31);
  147.   g = MIN(255, g);
  148.   br_b = 255 * ((br >> 10) & 0x1f);
  149.   b = MAX((2 * 2 * target_b) - (tl_b + br_r), 0) / (2*31);
  150.   b = MIN(255, b);
  151.   tr = map_palette_entry_to_16bpp_colour((r << 8) | (g << 16) | (b << 24));
  152.  
  153.   tr_r = 255 * ((tr >> 0) & 0x1f);
  154.   r = MAX((3 * 2 * target_r) - (tl_r + br_r + tr_r), 0) / (3*31);
  155.   r = MIN(255, r);
  156.   tr_g = 255 * ((tr >> 5) & 0x1f);
  157.   g = MAX((3 * 2 * target_g) - (tl_g + br_g + tr_g), 0) / (3*31);
  158.   g = MIN(255, g);
  159.   tr_b = 255 * ((tr >> 10) & 0x1f);
  160.   b = MAX((3 * 2 * target_b) - (tl_b + br_r + tr_b), 0) / (3*31);
  161.   b = MIN(255, b);
  162.   bl = map_palette_entry_to_16bpp_colour((r << 8) | (g << 16) | (b << 24));
  163.  
  164.   dither[0][0] = tl;
  165.   dither[0][1] = tr;
  166.   dither[1][0] = bl;
  167.   dither[1][1] = br;
  168. }
  169.  
  170.  
  171.  
  172. static bits map_palette_entry_to_16bpp_colour(
  173.                 os_colour       colour) {
  174.   int   red, grn, blu;
  175.  
  176.   red = ((colour << (2*8)) >> 24) & 0xff; red = ((red * 0x1f) + 0x80) >> 8;
  177.   grn = ((colour << (1*8)) >> 24) & 0xff; grn = ((grn * 0x1f) + 0x80) >> 8;
  178.   blu = ((colour << (0*8)) >> 24) & 0xff; blu = ((blu * 0x1f) + 0x80) >> 8;
  179.   return red | (grn << 5) | (blu << 10);
  180. }
  181.  
  182.  
  183.